home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / DJIO.C < prev    next >
C/C++ Source or Header  |  1994-12-12  |  14KB  |  592 lines

  1. /*****************************************************************************
  2.  * FILE: djio.c                                  *
  3.  *                                         *
  4.  * DESC:                                     *
  5.  *    - io library for djgpp support                         *
  6.  *                                         *
  7.  * Copyright (C) 1993,1994                             *
  8.  *    Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld             *
  9.  *    email: rainer@mathematik.uni-bielefeld.de                 *
  10.  *                                         *
  11.  *****************************************************************************/
  12.  
  13. /*
  14. ** source: libc from emx/gcc (c) Eberhard Mattes
  15. */
  16.  
  17. #include "DPMI.H"
  18. #include "RMLIB.H"
  19. #include "DOSERRNO.H"
  20. #include <stdarg.h>
  21. #include <stddef.h>
  22.  
  23. #ifdef __EMX__
  24.  
  25. /* from djgpp include files */
  26. #define O_RDONLY    0x0001
  27. #define O_WRONLY    0x0002
  28. #define O_RDWR        0x0004
  29. #define O_CREAT     0x0100
  30. #define O_TRUNC     0x0200
  31. #define O_EXCL        0x0400
  32. #define O_APPEND    0x0800
  33. #define O_NDELAY    0x2000
  34. #define O_TEXT        0x4000
  35. #define O_BINARY    0x8000
  36.  
  37. #define O_ACCMODE    0x07
  38.  
  39. #define O_NOINHERIT    0x0080
  40. #define O_DENYALL    0x0010
  41. #define O_DENYWRITE    0x0020
  42. #define O_DENYREAD    0x0030
  43. #define O_DENYNONE    0x0040
  44.  
  45. #define F_EOF        0x00000020
  46. #define F_TERMIO    0x00000040
  47. #define F_DEV        0x00000080
  48. #define F_NPIPE     0x00001000
  49.  
  50. #define S_IREAD 0x0100    /* owner may read */
  51. #define S_IWRITE 0x0080 /* owner may write */
  52. #define S_IEXEC 0x0040    /* owner may execute <directory search> */
  53.  
  54. #define SH_MASK       0x70
  55.  
  56. #define FALSE 0
  57. #define TRUE  1
  58.  
  59. int _fmode_bin = O_BINARY;
  60. int _nfiles = 40;
  61. long _files[40];
  62. int _lookahead[40];
  63.  
  64. typedef int (*OPENFUNC) (char *, WORD);
  65.  
  66. void djio_init(void)
  67. {
  68.     int j;
  69.     int handle;
  70.  
  71.     for (handle = 0; handle < 5; ++handle) {
  72.     _files[handle] = 0;
  73.     _lookahead[handle] = -1;
  74.     if ((j = rm_ioctl_getattr(handle)) != -1) {
  75.         _files[handle] |= O_TEXT;
  76.         if (j & 128)
  77.         _files[handle] |= F_DEV;
  78.         if (handle == 0)
  79.         _files[handle] |= O_RDONLY;
  80.         else if (handle == 1 || handle == 2)
  81.         _files[handle] |= O_WRONLY;
  82.         else
  83.         _files[handle] |= O_RDWR;
  84.     }
  85.     }
  86. }
  87.  
  88. void djio_dup_fileattr(int from, int to)
  89. {
  90.     if (to > 40)
  91.     return;
  92.     _files[to] = _files[from];
  93.     _lookahead[to] = _lookahead[from];
  94. }
  95.  
  96. static void *my_memchr(const void *s, unsigned char c, size_t n)
  97. {
  98.     if (n != 0) {
  99.     register const unsigned char *p = s;
  100.     do {
  101.         if (*p++ == c)
  102.         return ((void *) (p - 1));
  103.     } while (--n != 0);
  104.     }
  105.     return (void *) 0;
  106. }
  107.  
  108. static int do_ftruncate(int fh, long pos)
  109. {
  110.     long temp;
  111.  
  112.     if ((temp = rm_lseek(fh, 0, SEEK_END)) == -1)
  113.     return -1;
  114.     else if (temp > (long) pos)
  115.     if (rm_lseek(fh, pos, SEEK_SET) == -1 || rm_write(fh, 0, 0) == -1)
  116.         return -1;
  117.     return 0;
  118. }
  119.  
  120. static int do_open(char *buf, long flags)
  121. {
  122.     int i, dosfile;
  123.     OPENFUNC openfn;
  124.     unsigned p2;
  125.  
  126.     i = (int) (flags >> 16);    /* 1 = O_CREAT, 2 = O_EXCL, 4 = O_TRUNC */
  127.  
  128.     if (i & 0x01) {
  129.     if (i & 0x02)        /* O_CREAT | O_EXCL */
  130.         openfn = rm_creatnew;
  131.     else if (i & 4)     /* O_CREAT | O_TRUNC */
  132.         openfn = rm_creat;
  133.     else if (rm_access(buf, 0) == -1)    /* old file there ? */
  134.         openfn = rm_creat;
  135.     else
  136.         openfn = rm_open;
  137.     } else            /* not O_CREAT */
  138.     openfn = rm_open;
  139.  
  140.     if (openfn == rm_open) {
  141.     int rdwr = flags & O_ACCMODE;
  142.     rdwr >>= 1;
  143.     p2 = flags & 0xff;
  144.     p2 &= ~O_ACCMODE;
  145.     p2 |= rdwr;
  146.     }
  147.     else
  148.     p2 = (unsigned) flags >> 8;    /* creat attrib */
  149.  
  150.     dosfile = (*openfn) (buf, (WORD) p2);
  151.  
  152.     if (dosfile == -1)
  153.     return -1;
  154.     else {
  155.     if ((i & 0x05) == 0x4) {/* O_TRUNC with open */
  156.         if (do_ftruncate(dosfile, 0) < 0)
  157.         return -1;
  158.     }
  159.     return dosfile;
  160.     }
  161.  
  162. }
  163.  
  164. static int dj_sopen(char *name, int oflag, int shflag, int pmode)
  165. {
  166.     int handle, saved_errno;
  167.     long flags, bits, last;
  168.     char dummy, ctrlz_kludge = FALSE;
  169.  
  170.     if ((oflag & O_ACCMODE) == O_RDONLY && (oflag & (O_TRUNC | O_CREAT))) {
  171.     emx_errno = EMX_EINVAL;
  172.     return (-1);
  173.     }
  174.     bits = oflag & (O_ACCMODE | O_NDELAY | O_APPEND);
  175.     if (oflag & O_BINARY)
  176.      /* do nothing */ ;
  177.     else if (oflag & O_TEXT)
  178.     bits |= O_TEXT;
  179.     else if (_fmode_bin == 0)    /* neither O_TEXT nor O_BINARY given */
  180.     bits |= O_TEXT;
  181.  
  182.     if ((bits & O_TEXT) && (oflag & O_APPEND) && (oflag & O_ACCMODE) == O_WRONLY) {
  183.     /*
  184.      * The caller requests to open a text file for appending in
  185.      * write-only.    To remove the Ctrl-Z (if there is any), we have to
  186.      * temporarily open the file in read/write mode.
  187.      */
  188.  
  189.     flags = O_RDWR | (shflag & SH_MASK);
  190.     ctrlz_kludge = TRUE;
  191.     } else
  192.     flags = (oflag & O_ACCMODE) | (shflag & SH_MASK);
  193.  
  194.     if (oflag & O_CREAT) {
  195.     int attr = 0;
  196.     if (!(pmode & S_IWRITE))
  197.         attr |= _A_RDONLY;
  198.     flags |= (attr << 8) | 0x10000;
  199.     if (oflag & O_EXCL)
  200.         flags |= 0x20000;
  201.     }
  202.     if (oflag & O_TRUNC)
  203.     flags |= 0x40000;
  204.  
  205.     saved_errno = emx_errno;
  206.     handle = do_open(name, flags);
  207.     if (handle < 0 && ctrlz_kludge && emx_errno == EMX_EACCES) {
  208.     /* Perhaps read access is denied.  Try again. */
  209.     emx_errno = saved_errno;
  210.     ctrlz_kludge = FALSE;
  211.     flags = (flags & ~O_ACCMODE) | (oflag & O_ACCMODE);
  212.     handle = do_open(name, flags);
  213.     }
  214.     if (handle < 0)
  215.     return (-1);
  216.  
  217.     if (handle >= _nfiles) {
  218.     rm_close(handle);
  219.     emx_errno = EMX_EMFILE;
  220.     return (-1);
  221.     }
  222.     if (rm_ioctl_getattr(handle) & 0x80) {
  223.     bits |= F_DEV;
  224.     oflag &= ~O_APPEND;
  225.     }
  226.     if (!(bits & F_DEV) && (bits & O_TEXT)) {
  227.     last = rm_lseek(handle, -1L, SEEK_END);
  228.     if (last != -1 && rm_read(handle, &dummy, 1) == 1 && dummy == 0x1a)
  229.         do_ftruncate(handle, last); /* Remove Ctrl-Z) */
  230.     rm_lseek(handle, 0L, SEEK_SET);
  231.     }
  232.     if (ctrlz_kludge) {
  233.     /* Reopen the handle in write-only mode. */
  234.  
  235.     rm_close(handle);
  236.     flags = (flags & ~O_ACCMODE) | (oflag & O_ACCMODE);
  237.     flags &= ~0x20000;    /* Remove O_EXCL */
  238.     handle = do_open(name, flags);
  239.     if (handle < 0)
  240.         return (-1);
  241.     }
  242.     _files[handle] = bits;
  243.     _lookahead[handle] = -1;
  244.  
  245.     /*
  246.      * When opening a file for appending, move to the end of the file. This
  247.      * is required for passing the handle to a child process.
  248.      */
  249.  
  250.     if (!(bits & F_DEV) && (bits & O_APPEND))
  251.     rm_lseek(handle, 0L, SEEK_END);
  252.     emx_errno = saved_errno;
  253.  
  254.     return (handle);
  255. }
  256.  
  257. int dj_creat(char *buf) {
  258.     return dj_sopen(buf, O_CREAT | O_WRONLY | O_TRUNC,
  259.              O_DENYNONE, S_IREAD | S_IWRITE);
  260. }
  261.  
  262. int dj_open(char *buf, int flags) {
  263.     return dj_sopen(buf, flags, O_DENYNONE, S_IREAD | S_IWRITE);
  264. }
  265.  
  266. #define CTRL_Z 0x1a
  267.  
  268. int dj_write(int handle, void *buf, size_t nbyte)
  269. {
  270.     int out_cnt, lf_cnt, i, n, buf_cnt;
  271.     char *src, *p;
  272.     char tmp[1024];
  273.  
  274.     if (handle < 0 || handle >= _nfiles) {
  275.     emx_errno = EMX_EBADF;
  276.     return (-1);
  277.     }
  278.     if (_files[handle] & O_APPEND)
  279.     rm_lseek(handle, 0L, SEEK_END);
  280.     if (nbyte == 0)        /* Avoid truncation of file */
  281.     return (0);
  282.     src = buf;
  283.     if (_files[handle] & O_TEXT) {
  284.     out_cnt = lf_cnt = 0;
  285.     buf_cnt = 0;
  286.     p = (char *) my_memchr(src, '\n', nbyte);
  287.     if (p == NULL)
  288.         goto write_bin;
  289.     for (i = 0; i < (int) nbyte; ++i) {
  290.         if (src[i] == '\n') {
  291.         if (buf_cnt >= sizeof(tmp))
  292.             do {
  293.             n = rm_write(handle, tmp, buf_cnt);
  294.             if (n == -1)
  295.                 goto error;
  296.             out_cnt += n;
  297.             if (n != buf_cnt) {
  298.                 emx_errno = EMX_ENOSPC;
  299.                 return (-1);
  300.             }
  301.             buf_cnt = 0;
  302.             } while (0);
  303.         tmp[buf_cnt++] = '\r';
  304.         ++lf_cnt;
  305.         }
  306.         if (buf_cnt >= sizeof(tmp))
  307.         do {
  308.             n = rm_write(handle, tmp, buf_cnt);
  309.             if (n == -1)
  310.             goto error;
  311.             out_cnt += n;
  312.             if (n != buf_cnt) {
  313.             emx_errno = EMX_ENOSPC;
  314.             return (-1);
  315.             }
  316.             buf_cnt = 0;
  317.         } while (0);
  318.         tmp[buf_cnt++] = src[i];
  319.     }
  320.     if (buf_cnt != 0)
  321.         do {
  322.         n = rm_write(handle, tmp, buf_cnt);
  323.         if (n == -1)
  324.             goto error;
  325.         out_cnt += n;
  326.         if (n != buf_cnt) {
  327.             emx_errno = EMX_ENOSPC;
  328.             return (-1);
  329.         }
  330.         buf_cnt = 0;
  331.         } while (0);
  332.     return (out_cnt - lf_cnt);
  333.     }
  334.   write_bin:
  335.     n = rm_write(handle, src, nbyte);
  336.     if (n == -1)
  337.     goto error;
  338.     if (n == 0 && !((_files[handle] & F_DEV) && *src == CTRL_Z)) {
  339.     emx_errno = EMX_ENOSPC;
  340.     return (-1);
  341.     }
  342.     return (n);
  343.  
  344.   error:
  345.     return (-1);
  346. }
  347.  
  348. static int read_lookahead(int handle, void *buf, size_t nbyte)
  349. {
  350.     int i, n, saved_errno;
  351.     char *dst;
  352.  
  353.     i = 0;
  354.     dst = buf;
  355.     saved_errno = emx_errno;
  356.     if (nbyte > 0 && _lookahead[handle] != -1) {
  357.     *dst = (char) _lookahead[handle];
  358.     _lookahead[handle] = -1;
  359.     ++i;
  360.     --nbyte;
  361.     }
  362.     n = rm_read(handle, dst + i, nbyte);
  363.     if (n == -1) {
  364.     if (emx_errno == EMX_EAGAIN && i > 0) { /* lookahead and O_NDELAY */
  365.         emx_errno = saved_errno;/* hide EAGAIN */
  366.         return (i);     /* and be successful */
  367.     }
  368.     return (-1);
  369.     }
  370.     return (i + n);
  371. }
  372.  
  373. static long filelength(int handle)
  374. {
  375.     long cur, n;
  376.  
  377.     cur = rm_lseek(handle, 0L, SEEK_CUR);
  378.     if (cur == -1L)
  379.     return (-1L);
  380.     n = rm_lseek(handle, 0L, SEEK_END);
  381.     rm_lseek(handle, cur, SEEK_SET);
  382.     return (n);
  383. }
  384.  
  385. static long tell(int handle)
  386. {
  387.     long n;
  388.  
  389.     if (handle < 0 || handle >= _nfiles) {
  390.     emx_errno = EMX_EBADF;
  391.     return (-1L);
  392.     }
  393.     n = (long) rm_lseek(handle, 0L, SEEK_CUR);
  394.     if (n == -1)
  395.     return (n);
  396.     if (_lookahead[handle] >= 0)
  397.     --n;
  398.     return (n);
  399. }
  400.  
  401. static int _crlf(char *buf, size_t size, size_t * new_size)
  402. {
  403.     size_t src, dst;
  404.     char *p;
  405.  
  406.     p = my_memchr(buf, '\r', size);     /* Avoid copying until CR reached */
  407.     if (p == NULL) {        /* This is the trivial case */
  408.     *new_size = size;
  409.     return (0);
  410.     }
  411.     src = dst = p - buf;    /* Start copying here */
  412.     while (src < size) {
  413.     if (buf[src] == '\r') { /* CR? */
  414.         ++src;        /* Skip the CR */
  415.         if (src >= size) {    /* Is it the final char? */
  416.         *new_size = dst;/* Yes -> don't include in new_size, */
  417.         return (1);    /* notify caller         */
  418.         }
  419.         if (buf[src] != '\n')       /* CR not followed by LF? */
  420.         --src;        /* Yes -> copy the CR */
  421.     }
  422.     buf[dst++] = buf[src++];/* Copy a character */
  423.     }
  424.     *new_size = dst;
  425.     return (0);
  426. }
  427.  
  428. static int eof(int handle)
  429. {
  430.     long cur, len;
  431.  
  432.     if (handle < 0 || handle >= _nfiles) {
  433.     emx_errno = EMX_EBADF;
  434.     return (-1);
  435.     }
  436.     if (_files[handle] & F_EOF) /* Ctrl-Z reached */
  437.     return (1);
  438.     cur = tell(handle);
  439.     if (cur < 0)
  440.     return (-1);
  441.     len = filelength(handle);
  442.     if (len < 0)
  443.     return (-1);
  444.     return (cur == len);
  445. }
  446.  
  447. int dj_read(int handle, void *buf, size_t nbyte)
  448. {
  449.     int n;
  450.     size_t j, k;
  451.     char *dst, c;
  452.  
  453.     if (handle < 0 || handle >= _nfiles) {
  454.     emx_errno = EMX_EBADF;
  455.     return (-1);
  456.     }
  457.     if (nbyte > 0 && (_files[handle] & F_EOF))
  458.     return (0);
  459.     dst = buf;
  460.     n = read_lookahead(handle, dst, nbyte);
  461.     if (n == -1)
  462.     return (-1);
  463.     if ((_files[handle] & O_TEXT) && !(_files[handle] & F_TERMIO) && n > 0) {
  464.     /* special processing for text mode */
  465.     if (!(_files[handle] & (F_NPIPE | F_DEV)) && dst[n - 1] == 0x1a &&
  466.         eof(handle)) {
  467.         /* remove last Ctrl-Z in text files */
  468.         --n;
  469.         _files[handle] |= F_EOF;
  470.         if (n == 0)
  471.         return (0);
  472.     }
  473.     if (n == 1 && dst[0] == '\r') {
  474.         /* This is the tricky case as we are not allowed to decrement n  */
  475.         /* by one as 0 indicates end of file. We have to use look ahead. */
  476.         int saved_errno = emx_errno;
  477.         j = read_lookahead(handle, &c, 1);    /* look ahead */
  478.         if (j == -1 && emx_errno == EMX_EAGAIN) {
  479.         _lookahead[handle] = dst[0];
  480.         return (-1);
  481.         }
  482.         emx_errno = saved_errno;/* hide error */
  483.         if (j == 1 && c == '\n')    /* CR/LF ? */
  484.         dst[0] = '\n';  /* yes -> replace with LF */
  485.         else
  486.         _lookahead[handle] = c; /* no -> save the 2nd char */
  487.     } else {
  488.         if (_crlf(dst, n, &k))    /* CR/LF conversion */
  489.         _lookahead[handle] = '\r';      /* buffer ends with CR */
  490.         n = k;
  491.     }
  492.     }
  493.     return (n);
  494. }
  495.  
  496. int dj_setmode(int handle, int mode)
  497. {
  498.     int old_mode;
  499.  
  500.     if (handle < 0 || handle >= _nfiles) {
  501.     emx_errno = EMX_EBADF;
  502.     return (-1);
  503.     }
  504.     old_mode = ((_files[handle] & O_TEXT) ? O_TEXT : O_BINARY);
  505.     if (mode == O_BINARY)
  506.     _files[handle] &= ~O_TEXT;
  507.     else if (mode == O_TEXT)
  508.     _files[handle] |= O_TEXT;
  509.     else {
  510.     emx_errno = EMX_EINVAL;
  511.     return (-1);
  512.     }
  513.     return (old_mode);
  514. }
  515.  
  516. int dj_chmod(char *name, int pmode)
  517. {
  518.     WORD attr;
  519.  
  520.     if (rm_getfattr(name, &attr) == -1)
  521.     return (-1);
  522.     if (pmode & S_IWRITE)
  523.     attr &= ~1;
  524.     else
  525.     attr |= 1;
  526.     if (rm_setfattr(name, attr) == -1)
  527.     return -1;
  528.     return (0);
  529. }
  530.  
  531. #else
  532.  
  533. #include <fcntl.h>
  534. #include <io.h>
  535. #include <sys/types.h>
  536. #include <sys/stat.h>
  537.  
  538. #define DJO_RDONLY      0x0001
  539. #define DJO_WRONLY      0x0002
  540. #define DJO_RDWR      0x0004
  541. #define DJO_CREAT      0x0100
  542. #define DJO_TRUNC      0x0200
  543. #define DJO_EXCL      0x0400
  544. #define DJO_APPEND      0x0800
  545. #define DJO_TEXT      0x4000
  546. #define DJO_BINARY      0x8000
  547.  
  548. static int convert_dj_attr(int attr)
  549. {
  550.     int newattr = 0;
  551.     if (attr & DJO_RDONLY) newattr |= O_RDONLY;
  552.     if (attr & DJO_WRONLY) newattr |= O_WRONLY;
  553.     if (attr & DJO_RDWR  ) newattr |= O_RDWR  ;
  554.     if (attr & DJO_CREAT ) newattr |= O_CREAT ;
  555.     if (attr & DJO_TRUNC ) newattr |= O_TRUNC ;
  556.     if (attr & DJO_EXCL  ) newattr |= O_EXCL  ;
  557.     if (attr & DJO_APPEND) newattr |= O_APPEND;
  558.     if (attr & DJO_TEXT  ) newattr |= O_TEXT  ;
  559.     if (attr & DJO_BINARY) newattr |= O_BINARY;
  560.     return newattr;
  561. }
  562.  
  563. void djio_init(void) {};
  564.  
  565. void djio_dup_fileattr(int from, int to) {};
  566.  
  567. int dj_creat(char *buf)
  568. {
  569.     return creat(buf, S_IREAD | S_IWRITE);
  570. }
  571. int dj_open(char *buf, int flags)
  572. {
  573.     return open(buf, convert_dj_attr(flags), S_IREAD | S_IWRITE);
  574. }
  575. int dj_write(int handle, void *buf, size_t nbyte)
  576. {
  577.     return write(handle, buf, nbyte);
  578. }
  579. int dj_read(int handle, void *buf, size_t nbyte)
  580. {
  581.     return read(handle, buf, nbyte);
  582. }
  583. int dj_setmode(int handle, int mode)
  584. {
  585.     return setmode(handle, convert_dj_attr(mode));
  586. }
  587. int dj_chmod(char *name, int pmode)
  588. {
  589.     return chmod(name, pmode);
  590. }
  591. #endif
  592.